package com.ruoyi.common.utils;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.enums.common.State;
import com.ruoyi.common.exception.data.EntityDataUnusableException;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.util.Assert;


import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Classname BaseEntityUtils
 * @Author: sunluquan
 * @Date: 2022/2/24 15:49
 * @Description TODO
 * Entity基类 工具类
 */
public class BaseEntityUtils {

    /**
     * 过滤不可用的数据
     * @param data 过滤集合对象
     */
    public static void filterUnavailableData(@NotEmpty Collection<? extends BaseEntity> data){

        Iterator<? extends BaseEntity> iterator = data.iterator();

        while(iterator.hasNext()){

            if(!isUsableEntity(iterator.next())){
                iterator.remove();
            }

        }

    }

    /**
     * 过滤不可用的数据
     * @param tMap 过滤集合对象
     * @param <T>
     */
    public static <K extends Serializable,T extends BaseEntity> void filterUnavailableData(@NotEmpty Map<K, T> tMap){

        Iterator<Map.Entry<K, T>> iterator = tMap.entrySet().iterator();

        while (iterator.hasNext()){

            if(!isUsableEntity(iterator.next().getValue())){
                iterator.remove();
            }

        }
    }

    /**
     * 检测实体对象是否为可用对象
     * @param entity
     * @param <T>
     * @return
     */
    private static <T extends BaseEntity> boolean isUsableEntity(@NotNull T entity){

        return entity.getState() == State.OK;
    }

    /**
     * 检测数据是否可用
     * @param t 检测实体
     * @param throwEx 不可用时是否抛出异常 true 抛出 false 不抛出
     * @param <T>
     * @return
     */
    public static <T extends BaseEntity> boolean checkUsable(T t,boolean throwEx){

        Assert.notNull(t,"this argument is required; it must not be null");
        Assert.notNull(t.getState(),"this argument ["+t.getClass().getSimpleName()+".state ] is required; it must not be null");

        boolean usable = isUsableEntity(t);

        if(throwEx && !usable){
            throw new EntityDataUnusableException(t);
        }

        return usable;

    }

    /**
     * 检测数据是否可用 默认不可用抛出异常
     * @param t 检测实体
     * @param <T>
     * @return
     */
    public static <T extends BaseEntity> boolean checkUsable(T t){
        return checkUsable(t,true);
    }

    /**
     * 默认按照weight顺序排序
     * @param baseEntities
     * @return 排序后的对象
     */
    public static Collection<? extends BaseEntity> sort(Collection<? extends BaseEntity> baseEntities){

        return sort(baseEntities,true);
    }

    /**
     *
     * @param baseEntities
     * @param sortord 排序方式 true 顺序 ，false 逆序
     * @return 排序后的对象
     */
    public static Collection<? extends BaseEntity> sort(Collection<? extends BaseEntity> baseEntities,boolean sortord){

        if(StringUtils.isEmpty(baseEntities)){
            return baseEntities;
        }
        Stream<? extends BaseEntity> stream ;
        //
        if(sortord){
            stream = baseEntities.stream().sorted(Comparator.comparing(BaseEntity::getWeight));
        }else{
            stream = baseEntities.stream().sorted(Comparator.comparing(BaseEntity::getWeight).reversed());
        }

        if(baseEntities instanceof List){
            return stream.collect(Collectors.toList());
        }
        if(baseEntities instanceof Set){
            return stream.collect(Collectors.toSet());
        }
        return stream.collect(Collectors.toCollection(ArrayList::new));

    }
}
